package com.tj.shopping.util;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.List;

public class FileUploadUtil {
    private static final long FILEMAXSIZE = 1024 * 10 * 10;
    private static final String FILEPATH = "/shopping_pics";//文件的项目名
    private static String picsPath = "";//图片路径
    private static Method method = null;//存储的与图片相关的set方法


    /**
     * 文件上传  工具方法
     * 使用反射封装起来
     * @param req
     * @param cls
     * @param <T>
     * @return
     */
    public static <T> T uploadFile(HttpServletRequest req, Class<T> cls) {
        T t = null;
        Constructor<T> cs = null;//构造函数
        //获取所有的成员方法
        Method[] methods = cls.getDeclaredMethods();
        //获取磁盘项文件工厂   工厂设计
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //获取文件上传对象
        ServletFileUpload upload = new ServletFileUpload(factory);
        try {
            cs = cls.getConstructor();
            t = cs.newInstance();//创建文件
            //解析请求
            List<FileItem> list = upload.parseRequest(req);
            //循环所有表单元素  （普通的文件）
            for (Method m : methods) {
                for (FileItem f : list) {
                    String fieldName = f.getFieldName();//获取表单元素name属性值
                    if (("set" + fieldName).equalsIgnoreCase(m.getName())) {
                        setValue(req, m, t, f);
                    }
                }
            }
            //所有元素遍历完成  最后设置图片路径

            if (null != method && !StringUtils.isNull(picsPath)) {
                if (picsPath.lastIndexOf(";") == picsPath.indexOf(";")) {
                    picsPath = picsPath.substring(0, picsPath.indexOf(";"));
                }
                method.invoke(t, picsPath);
            }
            method = null;
            picsPath = "";

        } catch (Exception e) {
            System.out.println("文件上传封装代码异常" + e.getMessage());
            e.printStackTrace();
        }
        return t;
    }

    private static <T> void setValue(HttpServletRequest req, Method m, T t, FileItem f) throws Exception {
        if (f.isFormField()) {//是否为普通表单元素
            String name = f.getFieldName();
            String value = f.getString("UTF-8");
            //获取类型
            String typeName = m.getParameterTypes()[0].getSimpleName();
            if ("int".equals(typeName) || "Integer".equals(typeName)) {
                m.invoke(t, Integer.parseInt(value));
            } else if ("long".equals(typeName) || "Long".equals(typeName)) {
                m.invoke(t, Long.parseLong(value));
            } else if ("float".equals(typeName) || "Float".equals(typeName)) {
                m.invoke(t, Float.parseFloat(value));
            } else if ("double".equals(typeName) || "Double".equals(typeName)) {
                m.invoke(t, Double.parseDouble(value));
            } else {
                m.invoke(t, value);
            }
        } else {
            if (!StringUtils.isNull(f.getName())) {
                method = m;//将图片设置的set方法对象赋给method 全局变量
                //文件
                //获取web服务器的路径 拼接到图片项目的路径
                String path = req.getServletContext().getRealPath("/") + ".." + FILEPATH;
                //服务器中图片不能重名，否则会覆盖原有的
                String imageName = System.nanoTime() + f.getName();
                //创建文件对象
                File file = new File(path, imageName);
                //将文件上传中图片数据写入file对象中
                f.write(file);
                picsPath += ".." + FILEPATH + "/" + imageName + ";";
                //获取属性
                System.out.println("dsjofh");
            }

        }
    }

}
